gdk: Large GL refactoring
authorBenjamin Otte <otte@redhat.com>
Wed, 23 Nov 2016 02:32:22 +0000 (03:32 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 5 Dec 2016 14:02:47 +0000 (15:02 +0100)
No visible changes as GL rendering is disabled at the moment.

What was done:

1. Move window->invalidate_for_new_frame to glcontext->begin_frame
This moves the code to where it is used (the GLContext) and prepares it
for being called where it is used when actually beginning to draw the
frame.

2. Get rid of buffer-age usage
We want to let the application render directly to the backbuffer.
Because of that, we cannot make any assumptions about the contents the
application renders outside the clip area.
In particular GskGLRenderer renders random stuff there but not actual
contents.

3. Pass the actual GL context
Previously, we passed the shared context to end_frame, now we pass the
actual GL context that the application uses for rendering. This is so
that the vfuncs could prepare the actual contexts for rendering (they
don't currently).

4. Simplify the code
The previous code set up the final drawing method in begin_frame.
Instead, we now just ensure the clip area is something we can render
and decide on the actual method in end_frame.
This is both more robust (we can change the clip area in between if we
want to) and less code.

14 files changed:
gdk/gdkglcontextprivate.h
gdk/gdkwindow.c
gdk/gdkwindowimpl.h
gdk/mir/gdkmirglcontext.c
gdk/mir/gdkmirwindowimpl.c
gdk/wayland/gdkglcontext-wayland.c
gdk/wayland/gdkglcontext-wayland.h
gdk/wayland/gdkwindow-wayland.c
gdk/win32/gdkglcontext-win32.c
gdk/win32/gdkglcontext-win32.h
gdk/win32/gdkwindow-win32.c
gdk/x11/gdkglcontext-x11.c
gdk/x11/gdkglcontext-x11.h
gdk/x11/gdkwindow-x11.c

index 1d0b9ff32c4a9780c11cff5781e10c0b2609b7b0..24fd80ead3cff4997e42365fa27efd97e2fb8f86 100644 (file)
@@ -43,6 +43,8 @@ struct _GdkGLContextClass
   gboolean (* realize) (GdkGLContext *context,
                         GError **error);
 
+  void (* begin_frame)  (GdkGLContext *context,
+                         cairo_region_t *update_area);
   void (* end_frame)    (GdkGLContext *context,
                          cairo_region_t *painted,
                          cairo_region_t *damage);
index 5c7d7d716d402f27f44aa56cf169687e908875ad..f79cf4b2a7056b50087ca5d671cee453fb457baf 100644 (file)
@@ -3336,14 +3336,6 @@ gdk_window_process_updates_internal (GdkWindow *window)
 
          impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
 
-          /* Sometimes we can't just paint only the new area, as the windowing system
-           * requires more to be repainted. For instance, with OpenGL you typically
-           * repaint all of each frame each time and then swap the buffer, although
-           * there are extensions that allow us to reuse part of an old frame.
-           */
-          if (impl_class->invalidate_for_new_frame)
-            impl_class->invalidate_for_new_frame (window, expose_region);
-
          /* Clip to part visible in impl window */
          cairo_region_intersect (expose_region, window->clip_region);
 
index 82f7de984eeed7b1aacd366cded11e2bbb43ed20..e4539aba947735fd32d4cf88313c3984610afa9e 100644 (file)
@@ -299,8 +299,6 @@ struct _GdkWindowImplClass
                                           gboolean        attached,
                                            GdkGLContext   *share,
                                            GError        **error);
-  void         (*invalidate_for_new_frame)(GdkWindow      *window,
-                                           cairo_region_t *update_area);
 };
 
 /* Interface Functions */
index 9506461f1cffe971b9390657d6e705889823ce80..a4c00c211f05d6aa614eceb362e9f8ca1fa8d74e 100644 (file)
@@ -97,6 +97,25 @@ gdk_mir_gl_context_realize (GdkGLContext *context,
   return TRUE;
 }
 
+static void
+gdk_mir_gl_context_begin_frame (GdkGLContext   *context,
+                                cairo_region_t *update_area)
+{
+  GdkDisplay *display = gdk_gl_context_get_display (window);
+  GdkWindow *window;
+
+  if (_gdk_mir_display_have_egl_swap_buffers_with_damage (display))
+    return;
+
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
+}
+
 static void
 gdk_mir_gl_context_end_frame (GdkGLContext *context,
                               cairo_region_t *painted,
@@ -168,6 +187,7 @@ gdk_mir_gl_context_class_init (GdkMirGLContextClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   context_class->realize = gdk_mir_gl_context_realize;
+  context_class->begin_frame = gdk_mir_gl_context_begin_frame;
   context_class->end_frame = gdk_mir_gl_context_end_frame;
   gobject_class->dispose = gdk_mir_gl_context_dispose;
 }
index 7fc9376699520460764c63cbb3da3e97a57fb817..87c77e91b2d7221fcebedbe1b37a5ed3f98a8d35 100644 (file)
@@ -1595,67 +1595,6 @@ gdk_mir_window_impl_create_gl_context (GdkWindow     *window,
   return GDK_GL_CONTEXT (context);
 }
 
-static void
-gdk_mir_window_impl_invalidate_for_new_frame (GdkWindow *window,
-                                              cairo_region_t *update_area)
-{
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkMirGLContext *context_mir;
-  int buffer_age;
-  gboolean invalidate_all;
-  EGLSurface egl_surface;
-
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
-    return;
-
-  context_mir = GDK_MIR_GL_CONTEXT (window->gl_paint_context);
-  buffer_age = 0;
-
-  egl_surface = _gdk_mir_window_get_egl_surface (window, context_mir->egl_config);
-
-  if (_gdk_mir_display_have_egl_buffer_age (display))
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      eglQuerySurface (_gdk_mir_display_get_egl_display (display), egl_surface,
-                       EGL_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    invalidate_all = TRUE;
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
-}
-
 EGLSurface
 _gdk_mir_window_get_egl_surface (GdkWindow *window,
                                  EGLConfig config)
@@ -1830,5 +1769,4 @@ gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
   impl_class->set_opaque_region = gdk_mir_window_impl_set_opaque_region;
   impl_class->set_shadow_width = gdk_mir_window_impl_set_shadow_width;
   impl_class->create_gl_context = gdk_mir_window_impl_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_mir_window_impl_invalidate_for_new_frame;
 }
index 05043d1f8eaf7572a0ab7ad9f8a5cb9ad1b59991..c55e3070eb7ab0de4fc6f7d64eb4040131458ad4 100644 (file)
@@ -37,68 +37,19 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
 
 static void gdk_x11_gl_context_dispose (GObject *gobject);
 
-void
-gdk_wayland_window_invalidate_for_new_frame (GdkWindow      *window,
-                                             cairo_region_t *update_area)
+static void
+gdk_wayland_gl_context_begin_frame (GdkGLContext   *context,
+                                    cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
-  GdkWaylandGLContext *context_wayland;
-  int buffer_age;
-  gboolean invalidate_all;
-  EGLSurface egl_surface;
-
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
-    return;
-
-  context_wayland = GDK_WAYLAND_GL_CONTEXT (window->gl_paint_context);
-  buffer_age = 0;
-
-  egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
-                                                    context_wayland->egl_config);
-
-  if (display_wayland->have_egl_buffer_age)
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      eglQuerySurface (display_wayland->egl_display, egl_surface,
-                      EGL_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    invalidate_all = TRUE;
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
+  GdkWindow *window;
 
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-       * buffer is fully up-to-date for the swapbuffer
-       */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 #define N_EGL_ATTRS     16
@@ -227,13 +178,14 @@ gdk_wayland_gl_context_end_frame (GdkGLContext   *context,
   GdkWindow *window = gdk_gl_context_get_window (context);
   GdkDisplay *display = gdk_window_get_display (window);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
-  GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
+  GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
+  GdkWaylandGLContext *shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
   EGLSurface egl_surface;
 
-  gdk_gl_context_make_current (context);
+  gdk_gl_context_make_current (shared);
 
   egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window,
-                                                    context_wayland->egl_config);
+                                                    shared_wayland->egl_config);
 
   if (display_wayland->have_egl_swap_buffers_with_damage)
     {
@@ -266,6 +218,7 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
   gobject_class->dispose = gdk_x11_gl_context_dispose;
 
   context_class->realize = gdk_wayland_gl_context_realize;
+  context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
   context_class->end_frame = gdk_wayland_gl_context_end_frame;
 }
 
index 4908ba7968182cbbb8c89fb243a4dd4f8f1637f4..44a9510f700e53b51621a105dd3c1c39e29c4c00 100644 (file)
@@ -51,8 +51,6 @@ GdkGLContext *  gdk_wayland_window_create_gl_context                (GdkWindow
                                                                     gboolean           attach,
                                                                      GdkGLContext      *share,
                                                                      GError           **error);
-void            gdk_wayland_window_invalidate_for_new_frame         (GdkWindow         *window,
-                                                                     cairo_region_t    *update_area);
 gboolean        gdk_wayland_display_make_gl_context_current         (GdkDisplay        *display,
                                                                      GdkGLContext      *context);
 
index 4d1201592e4c41b10e577b3ce90b0e4c692e482d..603a0274ed9661bb24a33b2200bc0bc1cbdeda10 100644 (file)
@@ -3656,7 +3656,6 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
   impl_class->set_shadow_width = gdk_wayland_window_set_shadow_width;
   impl_class->show_window_menu = gdk_wayland_window_show_window_menu;
   impl_class->create_gl_context = gdk_wayland_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_wayland_window_invalidate_for_new_frame;
 
   signals[COMMITTED] = g_signal_new ("committed",
                                      G_TYPE_FROM_CLASS (object_class),
index ee80e0dc036b17aeb269f960315f0ae764ab991c..8da90a31ee5c0a962adf8468ccf37da66835b0f4 100644 (file)
@@ -81,23 +81,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
   G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
 }
 
-static void
-gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
-{
-  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-  context_class->end_frame = _gdk_win32_gl_context_end_frame;
-  context_class->realize = _gdk_win32_gl_context_realize;
-
-  gobject_class->dispose = _gdk_win32_gl_context_dispose;
-}
-
-static void
-gdk_win32_gl_context_init (GdkWin32GLContext *self)
-{
-}
-
 static void
 gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
 {
@@ -117,10 +100,10 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region)
     }
 }
 
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage)
+static void
+gdk_win32_gl_context_end_frame (GdkGLContext *context,
+                                cairo_region_t *painted,
+                                cairo_region_t *damage)
 {
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
   GdkWindow *window = gdk_gl_context_get_window (context);
@@ -149,7 +132,12 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
         }
     }
 
-  if (context_win32->do_blit_swap)
+  whole_window = (GdkRectangle) { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
+  if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN)
+    {
+      SwapBuffers (context_win32->gl_hdc);
+    }
+  else if (gdk_gl_context_has_framebuffer_blit (context))
     {
       glDrawBuffer(GL_FRONT);
       glReadBuffer(GL_BACK);
@@ -161,44 +149,28 @@ _gdk_win32_gl_context_end_frame (GdkGLContext *context,
         glFrameTerminatorGREMEDY ();
     }
   else
-    SwapBuffers (context_win32->gl_hdc);
+    {
+      g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
+      SwapBuffers (context_win32->gl_hdc);
+    }
 }
 
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area)
+static void
+gdk_win32_gl_context_begin_frame (GdkGLContext   *context,
+                                  cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  gboolean invalidate_all = FALSE;
-  GdkWin32GLContext *context_win32;
-  cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
+  GdkWindow *window;
 
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
+  if (gdk_gl_context_has_framebuffer_blit (context))
     return;
 
-  context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
-  context_win32->do_blit_swap = FALSE;
-
-  if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
-      cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
-    {
-      context_win32->do_blit_swap = TRUE;
-    }
-  else
-    invalidate_all = TRUE;
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  window = gdk_gl_context_get_window (context);
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 typedef struct
@@ -630,9 +602,9 @@ _set_pixformat_for_hdc (HDC              hdc,
   return TRUE;
 }
 
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error)
+static gboolean
+gdk_win32_gl_context_realize (GdkGLContext *context,
+                              GError **error)
 {
   GdkGLContext *share = gdk_gl_context_get_shared_context (context);
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
@@ -730,6 +702,24 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
   return TRUE;
 }
 
+static void
+gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
+{
+  GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  context_class->begin_frame = gdk_win32_gl_context_begin_frame;
+  context_class->end_frame = gdk_win32_gl_context_end_frame;
+  context_class->realize = _gdk_win32_gl_context_realize;
+
+  gobject_class->dispose = _gdk_win32_gl_context_dispose;
+}
+
+static void
+gdk_win32_gl_context_init (GdkWin32GLContext *self)
+{
+}
+
 GdkGLContext *
 _gdk_win32_window_create_gl_context (GdkWindow *window,
                                      gboolean attached,
index 6470b92a4fb4c0ee0f1a8c3310288d1b21d705e6..328f54a7930b3271b1963adc9f3d54c9e0d2fee0 100644 (file)
@@ -44,7 +44,6 @@ struct _GdkWin32GLContext
   /* other items */
   guint is_attached : 1;
   guint do_frame_sync : 1;
-  guint do_blit_swap : 1;
 };
 
 struct _GdkWin32GLContextClass
@@ -58,23 +57,10 @@ _gdk_win32_window_create_gl_context (GdkWindow *window,
                                      GdkGLContext *share,
                                      GError **error);
 
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
-                                            cairo_region_t *update_area);
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
-                                 cairo_region_t *painted,
-                                 cairo_region_t *damage);
-
 gboolean
 _gdk_win32_display_make_gl_context_current (GdkDisplay *display,
                                             GdkGLContext *context);
 
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
-                               GError **error);
-
 G_END_DECLS
 
 #endif /* __GDK_WIN32_GL_CONTEXT__ */
index cddd9ef1b551ddb1f68088ecc74c7e9485d42034..f6fdbf2edd4491256294a3a9a2bb37d335722c84 100644 (file)
@@ -6114,7 +6114,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
   impl_class->change_property = _gdk_win32_window_change_property;
   impl_class->delete_property = _gdk_win32_window_delete_property;
   impl_class->create_gl_context = _gdk_win32_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = _gdk_win32_window_invalidate_for_new_frame;
   impl_class->get_scale_factor = _gdk_win32_window_get_scale_factor;
   impl_class->get_unscaled_size = _gdk_win32_window_get_unscaled_size;
 }
index 77103b50e2f4922ce9ba08e858ee787fcbc52808..16ebb423ac55530c17d3ad4932290275202a4488 100644 (file)
@@ -119,79 +119,22 @@ maybe_wait_for_vblank (GdkDisplay  *display,
     }
 }
 
-void
-gdk_x11_window_invalidate_for_new_frame (GdkWindow      *window,
-                                         cairo_region_t *update_area)
+static void
+gdk_x11_gl_context_begin_frame (GdkGLContext   *context,
+                                cairo_region_t *update_area)
 {
-  cairo_rectangle_int_t window_rect;
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
-  Display *dpy = gdk_x11_display_get_xdisplay (display);
-  GdkX11GLContext *context_x11;
-  unsigned int buffer_age;
-  gboolean invalidate_all;
+  GdkWindow *window;
 
-  /* Minimal update is ok if we're not drawing with gl */
-  if (window->gl_paint_context == NULL)
+  if (gdk_gl_context_has_framebuffer_blit (context))
     return;
 
-  context_x11 = GDK_X11_GL_CONTEXT (window->gl_paint_context);
-
-  buffer_age = 0;
-
-  context_x11->do_blit_swap = FALSE;
-
-  if (display_x11->has_glx_buffer_age)
-    {
-      gdk_gl_context_make_current (window->gl_paint_context);
-      glXQueryDrawable(dpy, context_x11->drawable,
-                      GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
-    }
-
-
-  invalidate_all = FALSE;
-  if (buffer_age == 0 || buffer_age >= 4)
-    {
-      cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
-
-      if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
-          cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
-        {
-          context_x11->do_blit_swap = TRUE;
-        }
-      else
-        invalidate_all = TRUE;
-    }
-  else
-    {
-      if (buffer_age >= 2)
-        {
-          if (window->old_updated_area[0])
-            cairo_region_union (update_area, window->old_updated_area[0]);
-          else
-            invalidate_all = TRUE;
-        }
-      if (buffer_age >= 3)
-        {
-          if (window->old_updated_area[1])
-            cairo_region_union (update_area, window->old_updated_area[1]);
-          else
-            invalidate_all = TRUE;
-        }
-    }
-
-  if (invalidate_all)
-    {
-      window_rect.x = 0;
-      window_rect.y = 0;
-      window_rect.width = gdk_window_get_width (window);
-      window_rect.height = gdk_window_get_height (window);
-
-      /* If nothing else is known, repaint everything so that the back
-         buffer is fully up-to-date for the swapbuffer */
-      cairo_region_union_rectangle (update_area, &window_rect);
-    }
-
+  window = gdk_gl_context_get_window (context);
+  /* If nothing else is known, repaint everything so that the back
+     buffer is fully up-to-date for the swapbuffer */
+  cairo_region_union_rectangle (update_area, &(GdkRectangle) {
+                                                 0, 0,
+                                                 gdk_window_get_width (window),
+                                                 gdk_window_get_height (window) });
 }
 
 static void
@@ -218,25 +161,27 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
                               cairo_region_t *painted,
                               cairo_region_t *damage)
 {
-  GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
+  GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
+  GdkX11GLContext *shared_x11 = GDK_X11_GL_CONTEXT (shared);
   GdkWindow *window = gdk_gl_context_get_window (context);
   GdkDisplay *display = gdk_gl_context_get_display (context);
   Display *dpy = gdk_x11_display_get_xdisplay (display);
   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  GdkRectangle whole_window;
   DrawableInfo *info;
   GLXDrawable drawable;
 
-  gdk_gl_context_make_current (context);
+  gdk_gl_context_make_current (shared);
 
   info = get_glx_drawable_info (window);
 
-  drawable = context_x11->drawable;
+  drawable = shared_x11->drawable;
 
   GDK_NOTE (OPENGL,
             g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s",
                        (unsigned long) drawable,
                        (unsigned long) gdk_x11_window_get_xid (window),
-                       context_x11->do_frame_sync ? "yes" : "no"));
+                       shared_x11->do_frame_sync ? "yes" : "no"));
 
   /* if we are going to wait for the vertical refresh manually
    * we need to flush pending redraws, and we also need to wait
@@ -246,7 +191,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
    * GLX_SGI_swap_control, and we ask the driver to do the right
    * thing.
    */
-  if (context_x11->do_frame_sync)
+  if (shared_x11->do_frame_sync)
     {
       guint32 end_frame_counter = 0;
       gboolean has_counter = display_x11->has_glx_video_sync;
@@ -255,7 +200,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
       if (display_x11->has_glx_video_sync)
         glXGetVideoSyncSGI (&end_frame_counter);
 
-      if (context_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
+      if (shared_x11->do_frame_sync && !display_x11->has_glx_swap_interval)
         {
           glFinish ();
 
@@ -271,7 +216,12 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
         }
     }
 
-  if (context_x11->do_blit_swap)
+  whole_window = (GdkRectangle) { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window) };
+  if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN)
+    {
+      glXSwapBuffers (dpy, drawable);
+    }
+  else if (gdk_gl_context_has_framebuffer_blit (shared))
     {
       glDrawBuffer(GL_FRONT);
       glReadBuffer(GL_BACK);
@@ -279,13 +229,16 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
       glDrawBuffer(GL_BACK);
       glFlush();
 
-      if (gdk_gl_context_has_frame_terminator (context))
+      if (gdk_gl_context_has_frame_terminator (shared))
         glFrameTerminatorGREMEDY ();
     }
   else
-    glXSwapBuffers (dpy, drawable);
+    {
+      g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
+      glXSwapBuffers (dpy, drawable);
+    }
 
-  if (context_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
+  if (shared_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync)
     glXGetVideoSyncSGI (&info->last_frame_counter);
 }
 
@@ -828,6 +781,7 @@ gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   context_class->realize = gdk_x11_gl_context_realize;
+  context_class->begin_frame = gdk_x11_gl_context_begin_frame;
   context_class->end_frame = gdk_x11_gl_context_end_frame;
   context_class->texture_from_surface = gdk_x11_gl_context_texture_from_surface;
 
index 44cb0d5eb9312dba6a28d576e29a9ff710aa25cc..c00834fa1d2a5673f080a9f175a291a41e4e12b5 100644 (file)
@@ -47,8 +47,6 @@ struct _GdkX11GLContext
   guint is_attached : 1;
   guint is_direct : 1;
   guint do_frame_sync : 1;
-
-  guint do_blit_swap : 1;
 };
 
 struct _GdkX11GLContextClass
@@ -61,8 +59,6 @@ GdkGLContext *  gdk_x11_window_create_gl_context                (GdkWindow
                                                                 gboolean           attached,
                                                                  GdkGLContext      *share,
                                                                  GError           **error);
-void            gdk_x11_window_invalidate_for_new_frame         (GdkWindow         *window,
-                                                                 cairo_region_t    *update_area);
 gboolean        gdk_x11_display_make_gl_context_current         (GdkDisplay        *display,
                                                                  GdkGLContext      *context);
 
index 09de9b245fa120d6f2767b8de2e15600f323d6bc..c339a9d891eed6925ff987c8ec921bc7e1e52737 100644 (file)
@@ -5393,6 +5393,5 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
   impl_class->set_shadow_width = gdk_x11_window_set_shadow_width;
   impl_class->show_window_menu = gdk_x11_window_show_window_menu;
   impl_class->create_gl_context = gdk_x11_window_create_gl_context;
-  impl_class->invalidate_for_new_frame = gdk_x11_window_invalidate_for_new_frame;
   impl_class->get_unscaled_size = gdk_x11_window_get_unscaled_size;
 }